﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using YasharEl.Infrastructure.ApplicationModel.Bootstrap.Extensibility;
using YasharEl.Infrastructure.ApplicationModel.Bootstrap.Configuration;
using System.Configuration;
using YasharEl.Infrastructure.ObjectFactory.Configuration;
using YasharEl.Infrastructure.ObjectFactory.Adapters;
using YasharEl.Infrastructure.ApplicationModel.Modularity.Bootstrap;

namespace YasharEl.Infrastructure.ApplicationModel.Bootstrap.Extensions
{
    public class ObjectFactoryBootstrapperExtension : ModuleComponentBootstrappingExtension, IConsumeConfigurationSection
    {
        #region Properties

        public ObjectFactoryConfig ObjectFactoryConfigSection { get; private set; }

        #endregion

        #region IConsumeConfigurationSection Members

        public void Apply(ConfigurationSection section)
        {
            ObjectFactoryConfigSection = section as ObjectFactoryConfig;
        }

        #endregion

        #region BaseComplexBootstrappingExtension Describe

        public override string Describe()
        {
            return "Extension which configure and start object factory infrastructure component.";
        }

        #endregion

        #region BaseComplexBootstrappingExtension Configure

        public override void Configure()
        {
            base.Configure();

            if (ObjectFactoryConfigSection != null)
            {
                Logger.Info("Configuring object factory infrastructure component...");

                if (ObjectFactoryConfigSection.TypeAdapters != null && ObjectFactoryConfigSection.TypeAdapters.Count > 0)
                {
                    foreach (TypeAdapterMapRegistratorConfig registratorConfig in ObjectFactoryConfigSection.TypeAdapters)
                    {
                        Type typeAdapterMapRegistratorType = registratorConfig.MapRegistratorType;

                        Container.DependencyRegistrar.Register(
                            typeof(RegisterTypesMap),
                            typeAdapterMapRegistratorType,
                            typeAdapterMapRegistratorType.FullName,
                            false
                        );
                    }
                }

                Logger.Info("Object factory infrastructure component configured...");
            }
        }

        #endregion

        #region BaseComplexBootstrappingExtension Start

        public override void Start()
        {
            base.Start();

            Logger.Info("Starting object factory infrastructure component...");

            TypeAdapter typeAdapter = new TypeAdapter(
                Container
                    .DependencyResolver
                        .ResolveAllInstances<RegisterTypesMap>()
                        .ToArray()
            );

            Container.DependencyRegistrar.Register<ITypeAdapter>(typeAdapter, true);

            Logger.Info("{0} registered as default type adapter.", typeAdapter.GetType());
            typeAdapter
                .Maps
                    .Keys
                        .ToList()
                        .ForEach
                        (
                            (map) =>
                                Logger.Info("Type adapter contains types registrator of type : {0}", map)
                        );

            Logger.Info("Object factory infrastructure component started...");
        }

        #endregion

        #region ModuleComponentBootstrappingExtension Overrides

        public override string SectionName
        {
            get { return ObjectFactoryConfig.ObjectFactoryConfigDefaultSectionName; }
        }

        #endregion
    }
}
